﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Corss_LehaKondr
{
    public abstract class CrosswordWindowBase : Window
    {
        #region "const"
        private const uint defaultColumns = 10;
        private const uint defaultRows = 10;
        #endregion

        #region "protected"
        //protected CommandBinding addHAskBinding;
        //protected CommandBinding changeHAskBinding;
        //protected CommandBinding removeHAskBinding;

        protected virtual void OnCellsCountChanged(uint rows, uint cols)
        {

        }
        #endregion

        #region "Constructor"
        public CrosswordWindowBase()
        {
            this.CommandBindings.Add(new CommandBinding(_incHCell, (obj, e) =>
            {
                HorizontalCells++;
            }));
            this.CommandBindings.Add(new CommandBinding(_decHCell, (obj, e) =>
            {
                HorizontalCells--;
            }, (obj, e) =>
            {
                e.CanExecute = HorizontalCells > MinHCells;
            }));


            this.CommandBindings.Add(new CommandBinding(_incVCell, (obj, e) =>
            {
                VerticalCells++;
            }));
            this.CommandBindings.Add(new CommandBinding(_decVCell, (obj, e) =>
            {
                VerticalCells--;
            }, (obj, e) =>
            {
                e.CanExecute = VerticalCells > MinVCells;
            }));



            this.CommandBindings.Add(new CommandBinding(_addHAsk, (obj, e) =>
            {
                hAsks.Add(new Ask() { Answer = "Tst", TextAsk = "TstAsk" });
            }));

            this.CommandBindings.Add(new CommandBinding(_changeHAsk, (obj, e) =>
            {
                throw new NotImplementedException();
            }, (sender, e) =>
            {
                e.CanExecute = SelectedHAskIndex > -1;
            }));

            this.CommandBindings.Add(new CommandBinding(_removeHAsk, (obj, e) =>
            {
                if (MessageBox.Show("Вы действительно хотите удалить этот вопрос?", "Удалить этот вопрос?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    ((IList)hAsks).RemoveAt(SelectedHAskIndex);
            }, (sender, e) =>
            {
                e.CanExecute = SelectedHAskIndex > -1;
            }));


            Thread th = new Thread(() =>
            {
                this.Dispatcher.BeginInvoke(new ThreadStart(() =>
                {
                    OnCellsCountChanged(defaultRows, defaultColumns);
                }), null);
            });

            th.Start();
        }
        #endregion

        #region "private"
        private static bool validateCellsCount(object value)
        {
            uint val;
            if (value is uint)
                val = (uint)value;
            else if (value is string)
            {
                if (!uint.TryParse((string)value, out val))
                    return false;
            }
            else
                try
                {
                    val = (uint)value;
                }
                catch
                {
                    return false;
                }

            return val > 0;
        }
        #endregion

        #region "properies"
        public uint HorizontalCells
        {
            get { return (uint)GetValue(HorizontalCellsProperty); }
            set { SetValue(HorizontalCellsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HorizontalCells.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HorizontalCellsProperty =
            DependencyProperty.Register("HorizontalCells", typeof(uint), typeof(CrosswordWindowBase), new PropertyMetadata((uint)defaultColumns, (obj_i, e) =>
            {
                CrosswordWindowBase obj = (CrosswordWindowBase)obj_i;
                obj.OnCellsCountChanged(obj.VerticalCells, (uint)e.NewValue);
            }, (obj_i, e) =>
                {
                    CrosswordWindowBase obj = (CrosswordWindowBase)obj_i;

                    if ((uint)e < obj.MinHCells)
                        return obj.MinHCells;
                    return e;
                }), validateCellsCount);

        public uint VerticalCells
        {
            get { return (uint)GetValue(VerticalCellsProperty); }
            set { SetValue(VerticalCellsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for VerticalCells.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VerticalCellsProperty =
            DependencyProperty.Register("VerticalCells", typeof(uint), typeof(CrosswordWindowBase), new PropertyMetadata((uint)defaultRows, (obj_i, e) =>
            {
                CrosswordWindowBase obj = (CrosswordWindowBase)obj_i;
                obj.OnCellsCountChanged((uint)e.NewValue, obj.HorizontalCells);
            }, (obj_i, e) =>
                {
                    CrosswordWindowBase obj = (CrosswordWindowBase)obj_i;

                    if ((uint)e < obj.MinVCells)
                        return obj.MinVCells;
                    return e;
                }), validateCellsCount);

        public uint MinHCells
        {
            get { return (uint)GetValue(MinHCellsProperty); }
            set { SetValue(MinHCellsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MinHCells.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinHCellsProperty =
            DependencyProperty.Register("MinHCells", typeof(uint), typeof(CrosswordWindowBase), new PropertyMetadata((uint)1, (obj, e) =>
            {
                
            }), validateCellsCount);

        public uint MinVCells
        {
            get { return (uint)GetValue(MinVCellsProperty); }
            set { SetValue(MinVCellsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MinVCells.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinVCellsProperty =
            DependencyProperty.Register("MinVCells", typeof(uint), typeof(CrosswordWindowBase), new PropertyMetadata((uint)1), validateCellsCount);

        AskCollection _hAsks = new AskCollection();
        public AskCollection hAsks { get { return _hAsks; } }

        AskCollection _vAsks = new AskCollection();
        public AskCollection vAsks { get { return _vAsks; } }

        public int SelectedHAskIndex
        {
            get { return (int)GetValue(SelectedHAskIndexProperty); }
            set { SetValue(SelectedHAskIndexProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedHAskIndex.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedHAskIndexProperty =
            DependencyProperty.Register("SelectedHAskIndex", typeof(int), typeof(CrosswordWindowBase), new PropertyMetadata(-1));


        public int SelectedVAskIndex
        {
            get { return (int)GetValue(SelectedVAskIndexProperty); }
            set { SetValue(SelectedVAskIndexProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedVAskIndex.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedVAskIndexProperty =
            DependencyProperty.Register("SelectedVAskIndex", typeof(int), typeof(CrosswordWindowBase), new PropertyMetadata(-1));


        #endregion

        #region "Commands"
        static RoutedUICommand _incHCell = new RoutedUICommand("+", "incHCell", typeof(CrosswordWindowBase));
        public static RoutedUICommand incHCell { get { return _incHCell; } }

        static RoutedUICommand _decHCell = new RoutedUICommand("-", "decHCell", typeof(CrosswordWindowBase));
        public static RoutedUICommand decHCell { get { return _decHCell; } }



        static RoutedUICommand _incVCell = new RoutedUICommand("+", "incVCell", typeof(CrosswordWindowBase));
        public static RoutedUICommand incVCell { get { return _incVCell; } }

        static RoutedUICommand _decVCell = new RoutedUICommand("-", "decVCell", typeof(CrosswordWindowBase));
        public static RoutedUICommand decVCell { get { return _decVCell; } }



        static RoutedUICommand _addHAsk = new RoutedUICommand("Добавить", "addHAsk", typeof(CrosswordWindowBase));
        public static RoutedUICommand AddHAsk { get { return _addHAsk; } }

        static RoutedUICommand _changeHAsk = new RoutedUICommand("Изменить", "ChangeHAsk", typeof(CrosswordWindowBase));
        public static RoutedUICommand ChangeHAsk { get { return _changeHAsk; } }

        static RoutedUICommand _removeHAsk = new RoutedUICommand("Удалить", "RemoveHAsk", typeof(CrosswordWindowBase));
        public static RoutedUICommand RemoveHAsk { get { return _removeHAsk; } }



        static RoutedUICommand _addVAsk = new RoutedUICommand("Добавить", "addVAsk", typeof(CrosswordWindowBase));
        public static RoutedUICommand AddVAsk { get { return _addVAsk; } }

        static RoutedUICommand _changeVAsk = new RoutedUICommand("Изменить", "ChangeVAsk", typeof(CrosswordWindowBase));
        public static RoutedUICommand ChangeVAsk { get { return _changeVAsk; } }

        static RoutedUICommand _removeVAsk = new RoutedUICommand("Удалить", "RemoveVAsk", typeof(CrosswordWindowBase));
        public static RoutedUICommand RemoveVAsk { get { return _removeVAsk; } }

        #endregion
    }
}
